package com.lookme.lmtool.cracker.spliter;

import com.lookme.lmtool.cracker.annotation.ParamAnnotation;
import com.lookme.lmtool.cracker.annotation.SpliterAnnotation;
import com.lookme.lmtool.model.Rect;
import com.lookme.lmtool.model.SpliterInfo;
import com.lookme.lmtool.utils.ImageUtils;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import lombok.Getter;
import lombok.Setter;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
@SpliterAnnotation("投影分割")
@Getter@Setter
public class BlankSpliter extends AbstractSpliter {

    @XStreamAsAttribute
    @ParamAnnotation(name = "最小字符宽度", desc = "最小字符宽度",inputType = ParamAnnotation.InputType.Spinner,min=1)
    int minLength=3;


    @XStreamAsAttribute
    @ParamAnnotation(name = "最大字符宽度", desc = "最大字符宽度",inputType = ParamAnnotation.InputType.Spinner,min=1)
    int maxLength=25;

    @XStreamAsAttribute
    @ParamAnnotation(name = "平均值点数", desc = "平均值点数",inputType = ParamAnnotation.InputType.Spinner,min=0)
    int average=0;

    @XStreamAsAttribute
    @ParamAnnotation(name = "去空白边", desc = "去空白边",inputType = ParamAnnotation.InputType.Radio,width = 45)
    boolean removeBlank=false;

    @XStreamAsAttribute
    @ParamAnnotation(name = "最小的联通点", desc = "最小的联通点",inputType = ParamAnnotation.InputType.Spinner,min =1)
    int minPointCount=10;

    @Override
    public List<SpliterInfo> split(BufferedImage src) {
        List<SpliterInfo> subImgs = new ArrayList<SpliterInfo>();
        try {
            int width = src.getWidth();
            int height = src.getHeight();
            List<Integer> weightlist = new ArrayList<Integer>();
            for (int x = 0; x < width; ++x) {
                int count = 0;
                for (int y = 0; y < height; ++y) {
                    if (ImageUtils.isBlack(src.getRGB(x, y))) {
                        count++;
                    }
                }
                weightlist.add(count);
            }
            for (int i = 0; i < weightlist.size(); i++) {
                int length = 0;
                while (i < weightlist.size() &&( weightlist.get(i) > average||(length>0&&length<minLength))&&length<=maxLength) {
                    i++;
                    length++;
                }
                if (length >= maxLength) {
                    Rect rect=getBlankRectAndRemoveBlack(src,i- length);
                    if(removeBlank) {
                        rect = ImageUtils.getRemoveBlankRect(src, rect);
                    }
                    int point=ImageUtils.getRectPoint(src,rect);
                    if(point>=minPointCount) {
                        subImgs.add(SpliterInfo.get(src, rect));
                    }
                    i=rect.getX()+rect.getHeight();
                } else if (length >= minLength) {
                    Rect rect=Rect.builder().x(i-length).y(0).width(length).height(height).build();
                    if(removeBlank) {
                        rect = ImageUtils.getRemoveBlankRect(src, rect);
                    }
                    int point=ImageUtils.getRectPoint(src,rect);
                    if(point>=minPointCount) {
                        subImgs.add(SpliterInfo.get(src, rect));
                    }
                }
            }
        }catch (Exception e){

        }
        return subImgs;
    }


    public static Rect getBlankRectAndRemoveBlack(BufferedImage img,int startX){
        int width = img.getWidth();
        int height = img.getHeight();
        Rect rect=new Rect(startX,0,width,height,null);
        int minx=width,miny=height;
        int maxx=0,maxy=0;
        for (int x = startX; x < width; ++x) {
            boolean flag=false;
            for (int y = 0; y < height; ++y) {
                if(flag){
                    if (ImageUtils.isWhite(img.getRGB(x, y))) {
                        if(maxx<x){
                            maxx=x;
                        }
                        if(maxy<y){
                            maxy=y;
                        }
                    }
                }
                if (ImageUtils.isBlack(img.getRGB(x, y))) {
                    if(minx>x) {
                        minx = x;
                    }
                    if(miny>y) {
                        miny = y;
                    }
                    flag=true;
                    img.setRGB(x,y, Color.black.getRGB());
                }

            }
        }
        rect=new Rect(minx,miny,maxx-minx,maxy-miny,null);
        return rect;
    }

}
